<template>
  <div class="app-container">
    <splitpanes class="default-theme">
      <pane size="22" minSize="10" maxSize="30">
        <el-col >
          <el-card style="height: calc(100vh - 125px)">
            <div slot="header">
              <span><svg-icon icon-class="rpa" ></svg-icon> RPA配置</span>
            </div>
            <el-form ref="form" :model="form" :rules="rules">
              <el-descriptions direction="vertical" :column="1" border :label-style="{ width: '50%', fontWeight: 'bold' }" >
                <el-descriptions-item label="RPA开始时间设置">
                  <el-form-item>
                    <el-alert title="指定RPA开始时间" type="info" show-icon style="height: 40px" class="alert-info" :closable="false" />
                  </el-form-item>
                  <el-form-item label="模式" label-width="82px">
                    <el-radio-group v-model="form.modeType" @change="handleModeChange" :disabled="isLocked">
                      <el-tooltip class="item" effect="dark" content="继续执行：根据订单最新时间继续执行" placement="top-start">
                        <el-radio-button :label="1">模式一</el-radio-button>
                      </el-tooltip>
                      <el-tooltip class="item" effect="dark" content="覆盖执行：从指定时间运行，已存在的数据和文件全覆盖" placement="top-start">
                        <el-radio-button :label="2">模式二</el-radio-button>
                      </el-tooltip>
                      <el-tooltip class="item" effect="dark" content="跳过执行：从指定时间运行，跳过已自动处理的订单" placement="top-start">
                        <el-radio-button :label="2">模式三</el-radio-button>
                      </el-tooltip>
                    </el-radio-group>
                  </el-form-item>
                  <el-form-item label="开始时间" prop="startTime" v-if="form.modeType === 2 || form.modeType === 3" label-width="82px">
                    <el-date-picker
                      v-model="form.startTime"
                      type="datetime"
                      placeholder="选择开始时间"
                      format="yyyy-MM-dd HH:mm:00"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      date-format="yyyy-MM-dd HH:mm"
                      @change="handleStartTimeChange"
                      :disabled="isLocked">
                    </el-date-picker>
                  </el-form-item>
                </el-descriptions-item>
                <el-descriptions-item label="RPA结束时间设置">
                  <el-form-item>
                    <el-alert title="指定RPA结束时间；填写结束时间则程序运行到设定时间后停止" type="warning" show-icon style="height: 40px" class="alert-info" :closable="false" />
                  </el-form-item>
                  <el-form-item label="结束时间" prop="endTime" label-width="82px">
                    <el-date-picker
                      v-model="form.endTime"
                      type="datetime"
                      placeholder="选择结束时间"
                      format="yyyy-MM-dd HH:mm:59"
                      value-format="yyyy-MM-dd HH:mm:ss"
                      date-format="yyyy-MM-dd HH:mm"
                      :picker-options="endPickerOptions"
                      :disabled="isLocked">
                    </el-date-picker>
                  </el-form-item>
                </el-descriptions-item>
                <el-descriptions-item label="RPA操作">
                  <el-form-item>
                    <el-alert title="RPA操作，此过程不可逆，请谨慎使用" type="error" show-icon style="height: 40px" class="alert-info" :closable="false" />
                  </el-form-item>
                  <el-form-item align="center">
                    <el-button-group>
                      <el-button :type="isLocked ? 'danger' : 'success'" :icon="isLocked ? 'el-icon-lock' : 'el-icon-unlock'" @click=" isLocked = !isLocked;">{{ isLocked ? '解 锁' : '锁 定' }}</el-button>
                      <el-button type="primary" icon="el-icon-switch-button" :disabled="isLocked" @click="handleRun">执 行</el-button>
                    </el-button-group>
                  </el-form-item>
                </el-descriptions-item>
              </el-descriptions>
            </el-form>
          </el-card>
        </el-col>
      </pane>
      <pane>
        <el-col size="70">
          <el-card style="height: calc(100vh - 125px)">
            <div slot="header">
              <span><svg-icon icon-class="log"></svg-icon> RPA日志</span>
              <el-button
                style="float: right; padding: 3px 0"
                type="text"
                icon="el-icon-refresh-right"
              ></el-button>
            </div>
            <!-- 左侧工具栏 -->
            <div class="log-area">
              <div class="log-toolbar">
                <el-tooltip effect="dark" content="开启日志" placement="right">
                  <el-button
                    type="primary"
                    icon="el-icon-video-play"
                    circle
                    @click="openSocket">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="关闭日志" placement="right">
                  <el-button
                    type="danger"
                    icon="el-icon-switch-button"
                    circle
                    @click="closeSocket">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="全部日志" placement="right">
                  <el-button
                    type="primary"
                    icon="el-icon-document"
                    circle
                    @click="showAllLogs">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="错误日志" placement="right">
                  <el-button
                    type="danger"
                    icon="el-icon-warning-outline"
                    circle
                    @click="showErrorLogs">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="信息日志" placement="right">
                  <el-button
                    type="info"
                    icon="el-icon-info"
                    circle
                    @click="showInfoLogs">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="警告日志" placement="right">
                  <el-button
                    type="warning"
                    icon="el-icon-warning"
                    circle
                    @click="showWarnLogs">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="清空日志" placement="right">
                  <el-button
                    type="danger"
                    icon="el-icon-delete"
                    circle
                    @click="clearLogs">
                  </el-button>
                </el-tooltip>

                <el-tooltip effect="dark" content="滚动到末尾" placement="right">
                  <el-button
                    type="success"
                    icon="el-icon-bottom"
                    circle
                    @click="scrollToBottom">
                  </el-button>
                </el-tooltip>

              </div>

              <div class="log-container" >
                <div ref="logContent" class="log-content" @scroll="handleScroll">
                  <div
                    v-for="(log, index) in webSocketLogs"
                    :key="index"
                    class="log-line"
                    :class="{
                      'log-start': log.includes('正在获取RPA日志，请稍后'),
                      'log-close': log.includes('RPA日志已关闭'),
                      'log-info': log.includes('INFO'),
                      'log-error': log.includes('ERROR'),
                      'log-warn': log.includes('WARN')
                    }" >
                    {{ log }}
                  </div>
                </div>
              </div>
            </div>

          </el-card>
        </el-col>
      </pane>
    </splitpanes>
  </div>
</template>

<script>
import { Splitpanes, Pane } from "splitpanes";
import "splitpanes/dist/splitpanes.css";

export default {
  name: "RPAConfig",
  components: { Splitpanes, Pane},
  data() {
    // 自定义验证规则：结束时间不能早于开始时间
    const validateEndTime = (rule, value, callback) => {
      if (!value) return callback(); // 允许空值
      const start = new Date(this.form.startTime);
      const end = new Date(value);
      // 精确到分钟的比较（忽略秒和毫秒）
      start.setSeconds(0, 0);
      end.setSeconds(0, 0);

      if (end < start) {
        callback(new Error("结束时间不能早于开始时间"));
      } else {
        callback();
      }
    };
    return {
      // rpa配置弹窗
      open: false,
      // 表单参数
      form: {
        // 模式
        modeType: 1
      },
      endPickerOptions: {
        disabledDate: (time) => {
          if (!this.form.startTime) return false;
          const start = new Date(this.form.startTime);
          // 禁用比开始时间早的日期
          return time.getTime() < start.getTime();
        },
      },
      rules: {
        startTime: [
          {
            required: true,
            message: "开始时间不能为空",
            trigger: "blur",
            // 动态验证：模式二和模式三下验证
            validator: (rule, value, callback) => {
              if ([2, 3].includes(this.form.modeType) && !value) {
                callback(new Error("开始时间不能为空"));
              } else {
                callback();
              }
            }
          }
        ],
        endTime: [
          { validator: validateEndTime, trigger: "blur" }
        ],
        rpaRule: [
          {  required: true, message: "规则不能为空", trigger: "blur" }
        ]
      },
      socket: null,
      webSocketLogs: [],
      // 组件是否已挂载
      isComponentMounted: false,
      // 存储所有原始日志
      allLogs: [],
      // 当前日志过滤状态: 'all','error','info','warn'
      logFilter: 'all',
      // 是否锁定自动滚动
      autoScrollLocked: true,
      // 用户是否手动向上滚动
      userScrolledUp: false,
      // 初始高度
      logContainerHeight: '80vh',
      // 按钮是否锁定
      isLocked: true,
    };

  },
  methods: {
    /** 显示所有日志 */
    showAllLogs() {
      this.logFilter = 'all';
      this.webSocketLogs = [...this.allLogs];
      this.scrollToBottom();
    },
    /** 仅显示错误日志 */
    showErrorLogs() {
      this.logFilter = 'error';
      this.webSocketLogs = this.allLogs.filter(log =>
        log.includes('ERROR')
      );
      this.scrollToBottom();
    },
    /** 仅显示信息日志 */
    showInfoLogs() {
      this.logFilter = 'info';
      this.webSocketLogs = this.allLogs.filter(log =>
        !log.includes('ERROR') &&
        !log.includes('WARN') &&
        !log.includes('正在获取RPA日志') &&
        !log.includes('RPA日志已关闭')
      );
      this.scrollToBottom();
    },
    /** 仅显示警告日志 */
    showWarnLogs() {
      this.logFilter = 'warn';
      this.webSocketLogs = this.allLogs.filter(log =>
        log.includes('WARN')
      );
      this.scrollToBottom();
    },
    /** 清空日志时同时清空原始日志 */
    clearLogs() {
      this.webSocketLogs = [];
      this.allLogs = [];
      this.autoScrollLocked = true;
      this.userScrolledUp = false;
      this.$nextTick(this.scrollToBottom);
    },
    /** 打开websocket链接 */
    openSocket() {
      // 关闭旧的WebSocket连接
      if (this.socket) {
        this.closeSocket();
      }
      this.isComponentMounted = true;
      this.scrollToBottomAndLock(); // 使用锁定滚动
      this.socket = new WebSocket(process.env.VUE_APP_API_RPA_WEBSOCKET_URL)
      this.webSocketLogs.push('-------------》》》》》正在获取RPA日志，请稍后')
      this.socket.onmessage = (event) => {

        if (this.isComponentMounted) {
          // 将日志添加到原始日志存储
          this.allLogs.push(event.data);
          // 根据当前过滤状态决定是否显示
          if (this.logFilter === 'all') {
            this.webSocketLogs.push(event.data);
          } else if (this.logFilter === 'error' && event.data.includes('ERROR')) {
            this.webSocketLogs.push(event.data);
          } else if (this.logFilter === 'warn' && event.data.includes('WARN')) {
            this.webSocketLogs.push(event.data);
          } else if (this.logFilter === 'info' &&
            !event.data.includes('ERROR') &&
            !event.data.includes('WARN') &&
            !event.data.includes('正在获取RPA日志') &&
            !event.data.includes('RPA日志已关闭')) {
            this.webSocketLogs.push(event.data);
          }

          // 如果需要自动滚动，则滚动到底部
          if (this.autoScrollLocked) {
            this.scrollToBottom();
          }
        }
      };
    },
    /** 关闭websocket */
    closeSocket () {
      if (this.socket) {
        // 先移除所有事件监听器
        this.socket.onmessage = null;
        this.socket.onerror = null;
        this.socket.onclose = null;
        this.socket = null;
        this.webSocketLogs.push('-------------》》》》》RPA日志已关闭')
        this.scrollToBottomAndLock(); // 使用锁定滚动
      }
    },
    /** 处理滚动事件 */
    handleScroll() {
      const container = this.$refs.logContent;
      if (!container) return;
      // 计算用户是否滚动到底部（距离底部20px以内视为底部）
      const isAtBottom = container.scrollHeight - container.scrollTop - container.clientHeight <= 20;
      // 如果用户滚动到底部，则恢复自动滚动锁定
      if (isAtBottom) {
        this.autoScrollLocked = true;
        this.userScrolledUp = false;
      } else {
        // 用户向上滚动，取消自动滚动
        this.autoScrollLocked = false;
        this.userScrolledUp = true;
      }
    },
    /** 滚动到底部并锁定 */
    scrollToBottomAndLock() {
      this.scrollToBottom();
      this.autoScrollLocked = true;
      this.userScrolledUp = false;
    },
    /** 滚动到底部 */
    scrollToBottom() {
      this.$nextTick(() => {
        const container = this.$refs.logContent;
        if (container) {
          container.scrollTop = container.scrollHeight;
        }
      });
    },
    /** 模式切换处理 */
    handleModeChange(value) {
      if (value === 2) {
        this.form.endTime = null;
      } else {
        this.form.startTime = null; // 清空开始时间
        this.form.endTime = null;   // 清空结束时间
      }
    },
    /** 开始时间变化处理 */
    handleStartTimeChange() {
      if (this.form.modeType === 2) {
        // 模式二下修改开始时间时清空结束时间
        this.form.endTime = null;
      }
    },
    /** 执行按钮 */
    handleRun(){
      this.$refs["form"].validate(valid => {
        if (valid) {
          this.isLocked = true;
          // 打开websocket
          this.openSocket();
        }
      });
    }
  },
  //销毁页面之前，断开连接
  beforeDestroy() {
    this.isComponentMounted = false;
    this.closeSocket();
  },

};
</script>

<style scoped>
/* 日志区域布局 */
.log-area {
  display: flex;
  margin-top: 10px;
  height: 100%; /* 占满父容器 */
}

/* 工具栏样式 */
.log-toolbar {
  display: flex;
  flex-direction: column;
  height: calc(80vh - 20px);; /* 与左侧配置面板一致 */
  padding: 10px 5px;
  background-color: #1e1e1e; /* 与 .log-container 背景色一致 */
  border-radius: 4px 0 0 4px;
  border: 1px solid #2d2d2d; /* 使用更深的边框色以适应深色背景 */
  border-right: none;

  overflow-y: auto;
}

.log-toolbar .el-button {
  margin: 5px 0;
  width: 36px;
  height: 36px;

  /* 按钮整体样式 */
  color: #d4d4d4 !important;             /* 图标文字颜色 */
  border: none !important;               /* 去掉边框 */

  /* 鼠标悬停效果 */
  transition: all 0.2s ease-in-out;
}

/* 调整日志容器 */
.log-container {
  flex: 1;
  height: calc(80vh - 20px); /* 预留底部 20px */
  overflow: hidden;
  border: 1px solid #ddd;
  border-radius: 0 4px 4px 0;
  background-color: #1e1e1e;
  color: #d4d4d4;
  font-family: monospace;
  display: flex;
  flex-direction: column;
}

.log-content {
  height: 100%;
  overflow-y: auto;
  padding: 10px 10px 30px 10px; /* 增加底部 padding，预留空白 */
}

.log-line {
  white-space: pre-wrap;
  line-height: 1.5;
  border-bottom: 1px solid #2d2d2d;
  padding: 2px 0;
}

.log-start {
  color: #67C23A;
}
.log-close {
  color: #F56C6C;
}
.log-info {
  color: #409EFF;
}
.log-error {
  color: #F56C6C;
}
.log-warn {
  color: #E6A23C;
}
</style>
